/// <license>
/// Copyright (c) 2002-2008, DotNetNuke Corporation
/// All rights reserved
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
/// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
/// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
/// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
/// of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
/// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
/// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
/// DEALINGS IN THE SOFTWARE.
/// </license>

#region Using Statements

using System;
using System.ComponentModel;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using DotNetNuke.Common.Utilities;

using DotNetNuke.ModuleToolkit.Common;
using DotNetNuke.ModuleToolkit.Controls;

#endregion

namespace DotNetNuke.ModuleToolkit.Modules.Skinning.SkinObjects
{
    /// -----------------------------------------------------------------------------
    /// <summary>
    /// Defines a custom base class that adds functionality designed for Module Skin Objects
    /// </summary>
    /// <remarks>
    /// NOTE: Inheriting from this control is not required but highly recommended when designing
    /// Skin Objects.
    /// </remarks>
    /// <history>
    ///     [anurse]    12/22/2005  created
    ///     [cnurse]    01/30/2006  converted to C#/.NET 2
    /// </history>
    /// -----------------------------------------------------------------------------
    [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal),
    AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal),
    ToolboxItem(false)
    ]
    public class ModuleSkinObjectBase : 
        CompositeControl,
        ISkinObject
    {

        #region Private Fields

        private string _DataSourceID = Null.NullString;

        private SkinnedControl _ParentControl;
        private SkinnablePortalModuleBase _ParentModule;

        #endregion

        #region Protected Members

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets the Associated DataSource
        /// </summary>
        /// <history>
        /// 	[cnurse]	01/13/2007  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected BaseDataSource DataSource
        {
            get
            {
                BaseDataSource dataSource = null;
                if (!String.IsNullOrEmpty(DataSourceID))
                {
                    dataSource = ParentModule.FindSkinObject(DataSourceID) as BaseDataSource;
                }
                return dataSource;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets and sets the Default Css Class
        /// </summary>
        /// <history>
        ///     [cnurse]  03/18/2006  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        [Browsable(false)]
        protected virtual String DefaultCssClass
        {
            get
            {
                return "Normal";
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets the text to display
        /// </summary>
        /// <history>
        ///     [cnurse]  04/07/2006  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        [Browsable(false)]
        protected virtual string DisplayText
        {
            get { return Null.NullString; }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets the design time text to display
        /// </summary>
        /// <history>
        ///     [cnurse]  04/07/2006  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        [Browsable(false)]
        protected virtual string DesignTimeText
        {
            get { return Null.NullString; }
        }

        #endregion
        
        #region Public Properties

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets and sets the ID of the DataSource to use for this skin object
        /// </summary>
        /// <history>
        /// 	[cnurse]	01/13/2007  Created
        /// </history>
        /// -----------------------------------------------------------------------------
        [Browsable(true),
        DefaultValue(""),
        Description("Set the ID of the DataSource to use for this skin object.")]
        public string DataSourceID
        {
            get { return _DataSourceID; }
            set { _DataSourceID = value; }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets whether the module is in Add Mode
        /// </summary>
        /// <history>
        /// 	[cnurse]	09/06/2007	created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected bool IsAddMode
        {
            get
            {
                bool isAddMode = false;

                if (ParentModule != null && (ParentModule.IsAddMode))
                    isAddMode = true;

                return isAddMode;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets whether the module is in Edit Mode
        /// </summary>
        /// <history>
        /// 	[cnurse]	09/06/2007	created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected bool IsEditMode
        {
            get
            {
                bool isEditMode = false;

                if (ParentModule != null && (ParentModule.IsEditMode))
                    isEditMode = true;

                return isEditMode;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Provides the path to the local resource file provided by the module that contains this object
        /// </summary>
        /// <history>
        ///   [anurse]  12/22/2005  created
        /// </history>
        /// -----------------------------------------------------------------------------
        [Browsable(false)]
        public string LocalResourceFile
        {
            get
            {
                string _LocalResourceFile = String.Empty;
                if (this.ParentModule != null)
                {
                    _LocalResourceFile = this.ParentModule.LocalResourceFile;
                }
                return _LocalResourceFile;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The ModuleId of the module that this object is contained in
        /// </summary>
        /// <remarks>
        /// This property has a value of <see cref="Null.NullInteger"/> if the control is not sited on a 
        /// <see cref="SkinnablePortalModuleBase" /> control
        /// </remarks>
        /// <history>
        /// 	[cnurse]	12/23/2005	created
        /// 	[anurse]	1/3/2006	integrated into generic engine
        /// </history>
        /// -----------------------------------------------------------------------------
        [Browsable(false)]
        public int ModuleId
        {
            get
            {
                int _moduleId = Null.NullInteger;
                if (this.ParentModule != null)
                    _moduleId = this.ParentModule.ModuleId;
                return _moduleId;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Provides a reference to the module that this object is contained in
        /// </summary>
        /// <remarks>
        /// This property is null if the control is not sited on a <see cref="SkinnablePortalModuleBase" /> control
        /// </remarks>
        /// <history>
        ///   [anurse]  12/22/2005  created
        /// </history>
        /// -----------------------------------------------------------------------------
        [Browsable(false)]
        public SkinnablePortalModuleBase ParentModule
        {
            get
            {
                if (_ParentModule == null)
                    _ParentModule = ControlUtils.FindParent<SkinnablePortalModuleBase>(this);
                return _ParentModule;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets the name of this skin object
        /// </summary>
        /// <history>
        ///   [anurse]  1/4/2006  created
        /// </history>
        /// -----------------------------------------------------------------------------
        [Browsable(false)]
        public string SkinObjectName
        {
            get
            {
                return this.GetType().Name;
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// The TabModuleId of the module instance that this object is contained in
        /// </summary>
        /// <remarks>
        /// This property has a value of <see cref="Null.NullInteger"/> if the control is not sited on a 
        /// <see cref="SkinnablePortalModuleBase" /> control
        /// </remarks>
        /// <history>
        /// 	[cnurse]	10/07/2007	created
        /// </history>
        /// -----------------------------------------------------------------------------
        [Browsable(false)]
        public int TabModuleId
        {
            get
            {
                int _tabModuleId = Null.NullInteger;
                if (this.ParentModule != null)
                    _tabModuleId = this.ParentModule.TabModuleId;
                return _tabModuleId;
            }
        }

        #endregion

        #region Private Methods

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Finds the Parent Module of this skin object
        /// </summary>
        /// <returns>A SkinnablePortalModuleBase</returns>
        /// <history>
        /// 	[anurse]	08/11/2006	created
        /// </history>
        /// -----------------------------------------------------------------------------
        private SkinnablePortalModuleBase FindParentModule()
        {
            return FindParentModule(_ParentControl);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Finds the Parent Module of a SkinnedControl
        /// </summary>
        /// <returns>A SkinnablePortalModuleBase</returns>
        /// <history>
        /// 	[anurse]	08/11/2006	created
        /// </history>
        /// -----------------------------------------------------------------------------
        private SkinnablePortalModuleBase FindParentModule(SkinnedControl ctrl)
        {
            if (ctrl.Host.ParentControl is SkinnablePortalModuleBase)
                return (SkinnablePortalModuleBase)ctrl.Host.ParentControl;
            else if (ctrl.Host.ParentControl is SkinnedControl)
                return FindParentModule((SkinnedControl)ctrl.Host.ParentControl);
            else
                return ControlUtils.FindParent<SkinnablePortalModuleBase>(this);
        }

        #endregion

        #region Protected Methods

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// AddAttributesToRender adds attributes to the control
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="writer">An HtmlTextWriter</param>
        /// <history>
        /// 	[cnurse]	03/18/2006	created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            //Make sure the CssClass is set to the default for the control
            if (CssClass == String.Empty) CssClass = DefaultCssClass;

            //Render the style
            ControlStyle.AddAttributesToRender(writer);

            //Call the base control's method
            base.AddAttributesToRender(writer);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Loads the specified template file from the Skins/[skin_name]/[skin_object_name]/Templates folder
        /// or if that file does not exist loads the same file from Skins/_default/[skin_object_name]/Templates
        /// </summary>
        /// <param name="templateFile">The ASCX Template file name</param>
        /// <history>
        /// 	[anurse]	1/3/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected virtual ITemplate LoadSkinTemplate(string templateFile)
        {
            return LoadSkinTemplate(templateFile, false);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Loads the specified template file from either the local (Skins/[skin_name]/[skin_object_name]/Templates)
        /// template folder or the shared (Skins/[skin_name]/Templates) template folder
        /// </summary>
        /// <param name="templateFile">The ASCX Template file name</param>
        /// <param name="useShared">
        /// A boolean determining if the shared template folder is used to locate the template
        /// </param>
        /// <history>
        /// 	[anurse]	1/3/2006	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected virtual ITemplate LoadSkinTemplate(string templateFile, bool useShared)
        {
            ITemplate temp = null;
            if (this.ParentModule != null)
                temp = ParentModule.LoadTemplate(this.ParentModule.MapSkinPath(String.Format("{0}/{1}", Constants.FOLDER_Templates, templateFile)));
            return temp;
        }

		/// -----------------------------------------------------------------------------
        /// <summary>
        /// Localizes the specified string.
        /// </summary>
        /// <param name="key">The resource key to localize</param>
        /// <returns>The localized string</returns>
        /// <history>
        /// 	[anurse]	08/11/2006	created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected string LocalizeString(string key)
        {
            return LocalizeString(key, key, false);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Localizes the specified string using the <see cref="Localization"/> service.
        /// Returning the specified value if the key could not be localized
        /// </summary>
        /// <param name="key">The resource key to localize</param>
        /// <param name="defaultValue">The default value to return if localization fails</param>
        /// <returns>The localized string or the value of <paramref name="defaultValue"/> if localization fails</returns>
        /// <history>
        /// 	[anurse]	08/11/2006	created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected string LocalizeString(string key, string defaultValue)
        {
            return LocalizeString(key, defaultValue, false);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Localizes the specified string using the <see cref="Localization"/> service.
        /// Returning the specified value if the key could not be localized
        /// </summary>
        /// <param name="key">The resource key to localize</param>
        /// <param name="defaultValue">The default value to return if localization fails</param>
        /// <param name="useGlobalResources">A boolean specifying if global or local resources are to be used</param>
        /// <returns>The localized string or the value of <paramref name="defaultValue"/> if localization fails</returns>
        /// <history>
        /// 	[anurse]	08/11/2006	created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected string LocalizeString(string key, string defaultValue, bool useGlobalResources)
        {
            string localizedString = defaultValue;
            if (this.ParentModule != null)
                localizedString = this.ParentModule.LocalizeString(key, defaultValue, useGlobalResources);

            return localizedString;
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// RenderContents renders the contents of the control
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="writer">An HtmlTextWriter</param>
        /// <history>
        /// 	[cnurse]	04/07/2006	created
        /// </history>
        /// -----------------------------------------------------------------------------
        protected override void RenderContents(HtmlTextWriter writer)
        {
            if (DesignMode)
            {
                writer.Write(DesignTimeText);
            }
            else
            {
                writer.Write(DisplayText);
            }
        }

        #endregion

        #region ISkinObject Members

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Gets the <see cref="SkinnedControl"/> that this object is contained on.
        /// </summary>
        /// <history>
        ///   [anurse]  12/22/2005  created
        /// </history>
        /// -----------------------------------------------------------------------------
        [Browsable(false)]
        public SkinnedControl ParentControl
        {
            get
            {
                if (_ParentControl == null)
                    _ParentControl = ControlUtils.FindParent<SkinnedControl>(this);
                return _ParentControl;
            }
        }

        #endregion

    }
}
